#ifndef USERHANDLER_H
#define USERHANDLER_H

#include "pjsipwrapper.h"

#include <QMutexLocker>
#include <QMutex>

class PjApiUaAccountHandler;
class Account;
class UserHandler;
class UserCallback;

class UserCallback : public PjApiUaAccountCallback
{
public:

    UserCallback(UserHandler *handler);

    ~UserCallback();

    UserHandler *getUserHandler() const
    {
        return m_userHandler;
    }

    //call back
    void onIncomingCall(int account_id,
                                int call_id,
                                void *data);

    /**
     *  Request Name: (Note: Here we use SIP request message for Service
     *                                         Request/Response message)
     *  | Request/Response  | Service name  | Request ID |
     *   "Response::Blog::12324"
     */
    void onInfoRequest(int session_id,
                                std::string request_name,
                                std::string content_type,
                                unsigned long long content_length,
                                void *data);

    void onInfoResponse(int session_id,
                                std::string response_name,
                                std::string content_type,
                                unsigned long long content_length,
                                void *data);

    void onIMMessage(int call_id,
                            const std::string from,
                            const std::string to,
                            const std::string contact,
                            const std::string mime_type,
                            const std::string body);
    void onIMTyping(int call_id,
                            std::string from,
                            std::string to,
                            std::string contact,
                            bool isTyping);

    void onStatlessRequestReceived(std::string from,
                                std::string request_name,
                                std::string content_type,
                                unsigned long long content_length,
                                void *data);

private:

    UserHandler *m_userHandler;


};

class UserHandler
{
public:
    UserHandler(Account *account);

    ~UserHandler();

    //Must be called after initialize UserHandler instance
    void init();

    // start a session with to
    int startSession(std::string to);

    void acceptSession(int session_id);

    //to reject an incoming session
    void rejectSession(int session_id);

    //to terminate an active session
    void terminateSession(int session_id);


    PjApiUaAccountHandler *getPjApiHandler() const
    {
        return m_handler;
    }

    PjApiUaAccountCallback *getUserCallback();

    void sendPackageInSession(int call_id,
                            const std::string name,
                            const std::string content_type,
                            const void* content);

    void sendIMOutSession(std::string to_uri, std::string mime_type, std::string content);

    void sendIMTyping(std::string to_uri, bool is_typing);

    void sendPackageStateless(const std::string target_uri, const std::string from, const std::string to, const std::string contact,
                                const std::string pkg_name, const std::string content_type, const void* content);

private:

    void initAccount();

    void initConfig();

    void initCallback();

    PjApiUaAccountHandler *m_handler;

    Account *m_account;

    QMutex *m_mutex;

   // UserCallback *m_callback;


};
#endif
